/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package br;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Collection;
import java.util.Date;
import org.hibernate.Query;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.hibernate.classic.Session;
/**
 *
 * @author marcelo
 */
public class Db {

    public static SessionFactory factory;
    Session session;
    public static Configuration conf;
    
    public void connect(){
        if(conf == null){
            conf = new Configuration().configure();
            factory= conf.buildSessionFactory();
        }        
        session = factory.openSession();
        session.beginTransaction();
    }

    public boolean isConnected() {
        try{
            return session != null && !session.connection().isClosed();
        }
        catch(SQLException e){
            return false;
        }
    }

    public void disconnect(){
        if(session != null)
            return;
        session.flush();
        session.close();
    }

    public void commit(){
        if(session == null)
            return;
        session.getTransaction().commit();
    }

    public ResultSet executeResultSet(String sql)throws SQLException{
        factory= new Configuration().configure().buildSessionFactory();
        Connection c  = factory.openStatelessSession().connection();        
        PreparedStatement pstm = c.prepareStatement(sql);
        ResultSet rs = pstm.executeQuery();        
        c.close();
        return rs;
    }
    public void executeSQL(String sql) throws SQLException{
        factory= new Configuration().configure().buildSessionFactory();
        Connection c  = factory.openStatelessSession().connection();        
        PreparedStatement pstm = c.prepareStatement(sql);
        pstm.execute();
        c.commit();
        c.close();
    }

    public void executeSQL(String sql, Object... params) throws SQLException{        
        factory= new Configuration().configure().buildSessionFactory();
        Connection c  = factory.openStatelessSession().connection();
        c.setTransactionIsolation(c.TRANSACTION_SERIALIZABLE);
        PreparedStatement pstm = c.prepareStatement(sql);
        for (int i = 0; i<params.length; i++)
            pstm.setObject(i, params[i]);
        pstm.execute();
        c.close();
    }


    public <t> Collection<t> selectQuery(String query){
        if(session == null)
            connect();
        return session.createQuery(query).list();
    }

    public <t> Collection<t> selectNamedQuery(String queryName){
        if(session == null)
            connect();
        return session.getNamedQuery(queryName).list();
    }

    public <t> Collection<t> selectNamedQuery(String queryName, String[] paramNames, Object... paramValues){
        if(session == null)
            connect();        
        Query q = session.getNamedQuery(queryName);
        setParameters(q,paramNames,paramValues);
        return q.list();
    }

    private void setParameters(Query q,String[] paramNames, Object... paramValues){
         if(paramValues != null){
            for(int i=0;i<paramValues.length;i++){
                if(paramValues[i] instanceof String)
                    q.setString(paramNames[i], String.valueOf(paramValues[i]));
                else if(paramValues[i] instanceof Integer)
                    q.setInteger(paramNames[i], Integer.parseInt(String.valueOf(paramValues[i])));
                else if(paramValues[i] instanceof Date)
                    q.setDate(paramNames[i],(Date)paramValues[i]);
            }
        }
    }

    public <t> Collection<t> selectSQLQuery(String sql,String[] paramNames, Object... paramValues){
        if(session == null)
            connect();
        Query q = session.createSQLQuery(sql);
        setParameters(q,paramNames,paramValues);
        return q.list();
    }

    public <t> Collection<t> selectSQLQuery(String sql){
        if(session == null)
            connect();
        return session.createSQLQuery(sql).list();
    }

    public <t> Collection<t> select(String query,EQueryType type){
        switch(type){
            case Query : return selectQuery(query);
            case NamedQuery : return selectNamedQuery(query);
            default : return selectSQLQuery(query);
        }    
    }

    public <t> Collection<t> select(String query){
        return selectQuery(query);
    }

    public <t> void insert(t obj){
        if(session == null)
            connect();
        session.save(obj);
    }

    public <t> void delete(t obj){
        if(session == null)
            connect();
        session.delete(obj);
    }

    public <t> void update(t obj){
        if(session == null)
            connect();
        session.update(obj);
    }

}
